package com.tool.tcp;

import java.awt.image.BufferedImage;
import java.awt.image.WritableRaster;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.SoftReference;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

import org.come.bean.ConfigureBean;
import org.come.model.Configure;
import org.come.until.FileAesUtil;
import org.come.until.UserMessUntil;

import com.gl.util.Xy2Util;
import com.tool.image.Creepsskin;
import com.tool.image.ImageMixDeal;

/**
 * Sprite 工厂类<br>
 * @author Langlauf
 * @date
 */
public class SpriteFactory {
    /**动画播放每帧的间隔(ms)*/
    public static final int ANIMATION_INTERVAL = 100;
    /** 文件头标记 */
    static final String WAS_FILE_TAG = "SP";
    static final String WAS_FILE_TAGTWO = "SH";

    static final int TCP_HEADER_SIZE = 12;
    static final int TYPE_ALPHA = 0x00;// 前2位
    static final int TYPE_ALPHA_PIXEL = 0x20;// 前3位 0010 0000
    static final int TYPE_ALPHA_REPEAT = 0x00;// 前3位
    static final int TYPE_FLAG = 0xC0;// 2进制前2位 1100 0000
    static final int TYPE_PIXELS = 0x40;// 以下前2位 0100 0000
    static final int TYPE_REPEAT = 0x80;// 1000 0000
    static final int TYPE_SKIP = 0xC0; // 1100 0000
    /**动作类型*/
    public static String[] ActionType=new String[13];
    /**锁*/
    public static Object UPDATE_LOCK = new Object();
    /**预加载的tcp*/
    public static List<Object> loads=new ArrayList<>();
    public static TCPLoadThread thread;
    /**获取新方式素材索引*/
    public static Map<Long,HHOne[]> indexMap;
    /**索映射文件地址*/
    public static Map<Integer,FileRandom> indexFileMap;
    /**素材缺失代替*/
    public static Sprite[] fillIns=new Sprite[6];
    /**记录已加载的Sprite*/
    public static Map<String,SoftReference<Sprite>> TcpMap=new HashMap<>();
    /**记录新加载方式的Sprite*/
    public static Map<Long  ,SoftReference<Sprite>> TcpTwoMap=new HashMap<>();
    /**影子素材*/
    public static Sprite shadow;
    public static Sprite[] flyPartCloud;
    private Integer index;
    static Sprite tcp;
    public static final BufferedImage image=new BufferedImage(1,1,BufferedImage.TYPE_INT_ARGB);
    public static boolean ischangeskin ;
    static String[] vvv = new String[]{"hit.tcp", "magic.tcp", "defend.tcp", "guard.tcp", "die.tcp", "attack.tcp", "t2.tcp", "4001.tcp", "4002.tcp", "4003.tcp", "4004.tcp", "400509", "400535", "400314", "1237.tcp","4101.tcp", "4102.tcp", "4103.tcp"};
    public static List<PartOne> clouds = new ArrayList();
    static{
        //TODO 初始化模型动作
        ActionType[0]="walk";//走
        ActionType[1]="run";//跑
        ActionType[2]="stand";//站
        ActionType[3]="t1";//特效1
        ActionType[4]="hit";//被攻击
        ActionType[5]="magic";//法术
        ActionType[6]="defend";//防御
        ActionType[7]="guard";//进入战斗
        ActionType[8]="die";//死
        ActionType[9]="attack";//攻击
        ActionType[10]="attackrun";//攻击跑
        ActionType[11]="t2";//特效2
        ActionType[12]="t3";//特效3";

        indexFileMap=new HashMap<>();
        indexMap=new HashMap<>();//初始化

        try {
            File file=new File("skin/hh.init");
            if(file.exists()) {
                try (FileInputStream fis=new FileInputStream(file)) {
                    byte[] data = new byte[fis.available()];
                    fis.read(data);
                    SpriteHead randomIn=new SpriteHead(data);
                    randomIn.seek(2);
                    while (randomIn.available()>0) {
                        long skin=randomIn.readLong();
                        indexMap.put(skin,initHHOne(skin,randomIn));
                    }
                    randomIn.close();
                }
            }
        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
        }
        thread = new TCPLoadThread();
        thread.start();

        shadow=VloadSprite("skin/YZ.tcp", null);
        shadow.updateToTime(0, 0);
    }
    public static boolean k=false;

    /**初始化*/
    public static HHOne[] initHHOne(long skin,SpriteHead randomIn) throws IOException{
        HHOne[] ones=new HHOne[randomIn.read()];
        for (int i = 0; i < ones.length; i++) {
            HHOne one=new HHOne();
            one.setAct((byte)randomIn.read());
            long[] ls=new long[randomIn.read()];
            for (int j = 0; j < ls.length; j++) {
                ls[j]=randomIn.readLong();
            }
//          if (skin>>40>0) {//调整坐骑图层顺序
//              long a=ls[0];long b=ls[1];
//              ls[1]=a;     ls[0]=b;
//          }
            one.setLs(ls);
            ones[i]=one;
        }
        return ones;
    }
    /**清除未使用的Sprite 重置使用次数*/
    public static void ResetAndRemove(){
        try {
            String key;
            Iterator<String> it = TcpMap.keySet().iterator();
            while(it.hasNext()) {
                key=it.next();
                SoftReference<Sprite> a=TcpMap.get(key);
                if (a==null||a.get()==null||a.get().getUse()==0) {
                    it.remove();
                } else {
                    a.get().setUse(0);
                }
            }
            long keyLong;
            Iterator<Long> itLong = TcpTwoMap.keySet().iterator();
            while(itLong.hasNext()) {
                keyLong=itLong.next();
                SoftReference<Sprite> a=TcpTwoMap.get(keyLong);
                if (a==null||a.get()==null||a.get().getUse()==0) {
                    itLong.remove();
                } else {
                    a.get().setUse(0);
                }
            }
            int keyInt;
            Iterator<Integer> itInt=indexFileMap.keySet().iterator();
            while(itInt.hasNext()) {
                keyInt=itInt.next();
                FileRandom fileRandom=indexFileMap.get(keyInt);
                if (fileRandom==null||fileRandom.isEnd()) {
                    itInt.remove();
                }
            }
        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
        }
    }
    /**获取对应的索引加载文件*/
    public static synchronized FileRandom getFileRandom(int i){
        FileRandom fileRandom=indexFileMap.get(i);
        if (fileRandom==null) {
            try {
                fileRandom=new FileRandom("skin/"+i+".hh");
                indexFileMap.put(i, fileRandom);
            } catch (Exception e) {
                // TODO: handle exception
                e.printStackTrace();
            }
        }else {
            fileRandom.setUse(0);
        }
        return fileRandom;
    }
    /**预加载*/
    public static Sprite Prepare(long skin,int act) {
        SoftReference<Sprite> s = TcpTwoMap.get(skin);
        if (s == null || s.get() == null) {
            addLoad(((act==0||act==1||act==2||act==10)?TCPLoadThread.N0:TCPLoadThread.N1)+skin);
//          addLoad((TCPLoadThread.N0)+skin);
            return null;
        } else {
            return s.get();
        }
    }
    /**预加载*/
    public static Sprite Prepare(String path) {
        SoftReference<Sprite> s = TcpMap.get(path);
        if (s == null || s.get() == null) {
            addLoad(path);
            return null;
        } else {
            return s.get();
        }
    }
    /**添加预加载的tcp*/
    public static void addLoad(Object object) {
        if (object==null) {return;}
        synchronized (UPDATE_LOCK) {
            if (!loads.contains(object)) {
                loads.add(object);
                thread.setLoadTcp();
            }
        }
    }
    /**获取一个加载的路径*/
    public static Object getLoad(){
        synchronized (UPDATE_LOCK) {
            return loads.size()!=0?loads.get(0):null;
        }
    }
    /**移除一个加载路径*/
    public static void clearLoad(Object load){
        synchronized (UPDATE_LOCK) {
            loads.remove(load);
        }
    }

    static Map<String, Animation> cacheAnimation = new ConcurrentHashMap<>();

    static Animation animation;

    /**表情包加载*/
    public static Animation loadAnimation(String filename) {

        Animation animation1 = cacheAnimation.get(filename);
        if(animation1 != null){
            return animation1;
        }

        try {
            File file=new File(filename);
            if(file!=null&&file.exists()) {
                try (InputStream in=new FileInputStream(file)) {
                    byte[] buf = new byte[2];
                    in.read(buf);
                    String fag=new String(buf);
                    int version=fag.equals(WAS_FILE_TAG)?0:fag.equals(WAS_FILE_TAGTWO)?1:-1;
                    if (version>=0) {
                        buf = new byte[in.available()];
                        int a = 0, count = 0;
                        while (in.available() > 0) {
                            a = in.read(buf,count,in.available());
                            count += a;
                        }
                        SpriteHead randomIn = new SpriteHead(buf);
                        animation=randomIn.initTwo();
                    }
                }
            }
            //else { System.err.println("Warning: 找不到精灵的资源文件!"+filename); }
        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
        }
        if (animation==null) {
            animation=new Animation();
            Frame frame=new Frame(image, 0, 0);
            animation.addFrame(frame);
        }

        cacheAnimation.put(filename, animation);
        return animation;
    }
    /**直接获取 新加载方式获取*/
    public static Sprite VloadSprite(long skin,boolean is,String value) {
        Sprite sprite=null;
        try {
            FileRandom fileRandom=getFileRandom((int)(skin>>32));
            if (fileRandom!=null) {
                byte[] bs=new byte[4];
                fileRandom.read(skin&0x7fffffff, bs);
                int size=0;
                for (int i = 0; i < bs.length; i++) {int v=(bs[i] & 0xff);v=v<<(8*i);size+=v;}
                bs=new byte[size];
                fileRandom.read((skin+4)&0x7fffffff, bs);
                SpriteHead randomIn = new SpriteHead(bs);
                sprite=randomIn.init(value,is,1);
            }
        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
        }
        if (sprite==null){//获取固定素材
            sprite=getFillIn(1);
        }
        return sprite;
    }
    /**直接获取 按路径去获取*/
    public static Sprite VloadSprite(String filename,String value) {
        if (filename==null||filename.length()==0) {return null;}
        Sprite sprite=null;
        try {
            File file=new File(filename);
            if(file!=null&&file.exists()) {
                try (InputStream in=new FileInputStream(file)) {
                    byte[] buf = new byte[2];
                    in.read(buf);
                    String fag=new String(buf);
                    int version=fag.equals(WAS_FILE_TAG)?0:fag.equals(WAS_FILE_TAGTWO)?1:-1;
                    if (Objects.equals(fag, "SW")) {
                        version=1;//幻方
                    }
                    if (version>=0) {
                        buf = new byte[in.available()];
                        int a = 0, count = 0;
                        while (in.available() > 0) {
                            a = in.read(buf,count,in.available());
                            count += a;
                        }
                        SpriteHead randomIn = new SpriteHead(buf);
                        sprite=randomIn.init(value,isV(filename),version);
                    }
                }
            }
//          else { System.err.println("Warning: 找不到精灵的资源文件!"+filename); }
        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
        }
        if (sprite==null&&(value==null||value.length()>0)){//获取固定素材  不是固定素材加载
            sprite=getFillIn(getAct(filename));
        }
        return sprite;
    }
    /**指定着色方案*/
    public static void assignColor(short[] palette,String value){
        try {
            String[] v=value.split("\\|");
            int sum=Integer.parseInt(v[0]);
            int start=Integer.parseInt(v[1]);
            int end=0;
            for (int i = 1; i <=sum; i++) {
                start=end;
                end=Integer.parseInt(v[i+1]);
                ColorationScheme scheme=new ColorationScheme(v,sum+2+(i-1)*9);
                for (int j = start; j < end; j++) {
                    palette[j] = scheme.mix(palette[j]);
                }
            }
        } catch (Exception e) {
            // TODO: handle exception
            System.err.println("错误格式的着色方案");
        }
    }
    /** 素材缺失代替*/
    public static Sprite getFillIn(int act){
        int value=0;
        if (act==1||act==0||act==10){
            value=1;
        }else if (act==2||act==7){
            value=2;
        }else if (act==4||act==6){
            value=3;
        }else if (act==5||act==3||act==9||act==11||act==12){
            value=4;
        }else if (act==8){
            value=5;
        }
        Sprite sprite=fillIns[value];
        if (sprite==null){
            String path=null;
            if (value==1){//站立 火柴人
                path="skin/000000/run.tcp";
            }else if (value==2){//跑 火柴人
                path="skin/000000/stand.tcp";
            }else if (value==3){//被攻击 火柴人
                path="skin/000000/hit.tcp";
            }else if (value==4){//法术 火柴人
                path="skin/000000/magic.tcp";
            }else if (value==5){//墓碑
                path="resource/FightingSkill/持续状态/墓碑.tcp";
            }else{//特效素材
                path = "resource/FightingSkill/10251.tcp";
            }
            sprite=VloadSprite(path,"");
            fillIns[value]=sprite;
        }
        return  sprite;
    }
    /**二次加载 （图片加载）*/
    public static void VloadImg(Sprite sprite) {
        synchronized (sprite) {

            int loadDir=sprite.getLoad();
            int count  =sprite.getFrameCount();
            if (loadDir==-1) {return;}
            loadDir%=sprite.getAnimationCount();

            //判断是否需要共用的方向
            boolean is=false;
            if (sprite.getAnimationCount()==4||sprite.getAnimationCount()==8) {
                is=true;
                if (loadDir==1) { loadDir=0; }
                else if(loadDir==3) { loadDir=2; }
                else if(loadDir==7) { loadDir=5; }
            }

            //避免重复加载图片
            if (sprite.getLoadFrame(loadDir).getImage()!=null) {return;}
            SpriteHead in=sprite.getHead();
            if (in!=null) {
                for (int i = 0; i < count; i++) {
                    Frame frame=sprite.getFrames()[loadDir*count+i];
                    BufferedImage bufferedImage=createDraw(in, frame, sprite);
                    frame.setImage(bufferedImage);
                }
            }else {//使用默认的1*1图片
                for (int i = 0; i < count; i++) {
                    sprite.getFrames()[loadDir*count+i].setImage(image);
                }
            }
            if (is) {//对象转换
                if (loadDir==0) {     sprite.translate(0, 1); }
                else if(loadDir==2) { sprite.translate(2, 3); }
                else if(loadDir==5) { sprite.translate(5, 7); }
            }
            sprite.removeHead();//加载完毕
        }
    }
    public static BufferedImage createDraw(SpriteHead in, Frame frame,Sprite sprite){
        try {
            if (frame.getPos()==0) { return image; }
            in.seek(frame.getPos());
            int frameX = in.readInt();
            int frameY = in.readInt();
            if (sprite.getFrameCount()==1) {
                frameX=sprite.getRefPixelX();
                frameY=sprite.getRefPixelY();
            }
            int frameWidth = in.readInt();
            int frameHeight = in.readInt();
            if (frameHeight>1000) {
                System.err.println("报警:"+frameHeight);
                if (frameHeight>=5000) { return image; }//严重报警
            }
            int[] lineOffsets = new int[frameHeight];
            for (int l = 0; l < frameHeight; l++) {
                lineOffsets[l] = in.readInt();
            }
            frame.setRefPixelX(frameX);frame.setRefPixelY(frameY);
            if (frameWidth==0||frameHeight==0) { return image; }
            short[] palette=in.getPalette();
            BufferedImage image = new BufferedImage(frameWidth,frameHeight,BufferedImage.TYPE_INT_ARGB);
            WritableRaster raster=image.getRaster();
            int[] iArray=new int[4];
            int b, x, c;
            int index;
            int count;
            for (int y = 0; y < frameHeight; y++) {
                x = 0;
                in.seek(lineOffsets[y]+frame.getPos());
                ss:while (x < frameWidth) {
                    b = in.read();
                    switch ((b & TYPE_FLAG)) {
                        case TYPE_ALPHA:
                            if ((b & TYPE_ALPHA_PIXEL) > 0) {
                                index = in.read();
                                c = palette[index];
                                iArray[0]=((c >>> 11) & 0x1F);
                                iArray[1]=((c >>> 5 ) & 0x3f);
                                iArray[2]=c & 0x1F;
                                iArray[0]=(iArray[0]<<3)|(iArray[0]&7);
                                iArray[1]=(iArray[1]<<2)|(iArray[1]&3);
                                iArray[2]=(iArray[2]<<3)|(iArray[2]&7);
                                iArray[3]=(b & 0x1F)<<3|(b&7);
                                raster.setPixel(x++, y, iArray);
                            } else if (b != 0) {// ???
                                count = b & 0x1F;// count
                                b = in.read();// alpha
                                index = in.read();
                                c = palette[index];
                                iArray[0]=((c >>> 11) & 0x1F);
                                iArray[1]=((c >>> 5 ) & 0x3f);
                                iArray[2]=( c & 0x1F);
                                iArray[0]=(iArray[0]<<3)|(iArray[0]&7);
                                iArray[1]=(iArray[1]<<2)|(iArray[1]&3);
                                iArray[2]=(iArray[2]<<3)|(iArray[2]&7);
                                iArray[3]=(b & 0x1F)<<3|(b&7);
                                for (int i = 0; i < count; i++) {
                                    raster.setPixel(x++, y, iArray);
                                }
                            } else {// block end
                                if (x==0 &&y > 0) {//x还是0的时候 复制上一行的数据
                                    int yTwo = y - 1;
                                    for (int i = x; i < frameWidth; i++) {
                                        raster.setPixel(i, y, raster.getPixel(i, yTwo, iArray));
                                    }
                                }
                                break ss;
                            }
                            break;
                        case TYPE_PIXELS:
                            count = b & 0x3F;
                            for (int i = 0; i < count; i++) {
                                index = in.read();
                                if (index != -1) {
                                    iArray[0]=((palette[index] >>> 11) & 0x1F);
                                    iArray[1]=((palette[index] >>> 5 ) & 0x3f);
                                    iArray[2]=( palette[index] & 0x1F);
                                    iArray[0]=(iArray[0]<<3)|(iArray[0]&7);
                                    iArray[1]=(iArray[1]<<2)|(iArray[1]&3);
                                    iArray[2]=(iArray[2]<<3)|(iArray[2]&7);
                                    iArray[3]= 0xFF;
                                    raster.setPixel(x++, y, iArray);
                                }
                            }
                            break;
                        case TYPE_REPEAT:
                            count = b & 0x3F;
                            index = in.read();
                            c = palette[index];
                            iArray[0]=((c >>> 11) & 0x1F);
                            iArray[1]=((c >>> 5 ) & 0x3f);
                            iArray[2]=( c & 0x1F);
                            iArray[0]=(iArray[0]<<3)|(iArray[0]&7);
                            iArray[1]=(iArray[1]<<2)|(iArray[1]&3);
                            iArray[2]=(iArray[2]<<3)|(iArray[2]&7);
                            iArray[3]= 0xFF;
                            for (int i = 0; i < count; i++) {
                                raster.setPixel(x++, y, iArray);
                            }
                            break;
                        case TYPE_SKIP:
                            count = b & 0x3F;
                            x += count;
                            break;
                        default:
                            break ss;
                    }
                }
                if (x > frameWidth) {
                    System.err.println("block end error: [" + y + "][" + x + "/" + frameWidth + "]");
                }
            }
//           /* if (sprite.getHighlight()) {
//                GlowFilter glowFilter = new GlowFilter();
//                glowFilter.setAmount(0.2f);
//                glowFilter.filter(image, image);
//            }*/
            return image;
        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
        }
        return image;
    }
    public static BufferedImage createDrawTwo(SpriteHead in, Frame frame,int frameCount,int refPixelX,int refPixelY,int width,int height){
        try {
            if (frame.getPos()==0) { return image; }
            in.seek(frame.getPos());
            int dx = in.readInt();
            int dy = in.readInt();
            frame.setRefPixelX(dx);frame.setRefPixelY(dy);
            if (frameCount==1) {
                dx=refPixelX;
                dy=refPixelY;
            }
            int frameWidth = in.readInt();
            int frameHeight = in.readInt();
            int[] lineOffsets = new int[frameHeight];
            for (int l = 0; l < frameHeight; l++) {
                lineOffsets[l] = in.readInt();
            }
            if (frameWidth==0||frameHeight==0) { return image; }
            short[] palette=in.getPalette();
            BufferedImage image = new BufferedImage(width, height,BufferedImage.TYPE_INT_ARGB);
            WritableRaster raster=image.getRaster();
            dx = refPixelX - dx;
            dy = refPixelY - dy;
            int[] iArray=new int[4];
            int b, x, c;
            int index;
            int count;
            for (int y = 0; y + dy<height && y < frameHeight; y++) {
                x = 0;
                in.seek(lineOffsets[y]+frame.getPos());
                ss:while (x < frameWidth) {
                    b = in.read();
                    switch ((b & TYPE_FLAG)) {
                        case TYPE_ALPHA:
                            if ((b & TYPE_ALPHA_PIXEL) > 0) {
                                index = in.read();
                                c = palette[index];
                                iArray[0]=((c >>> 11) & 0x1F);
                                iArray[1]=((c >>> 5 ) & 0x3f);
                                iArray[2]=( c & 0x1F);
                                iArray[0]=(iArray[0]<<3)|(iArray[0]&7);
                                iArray[1]=(iArray[1]<<2)|(iArray[0]&3);
                                iArray[2]=(iArray[2]<<3)|(iArray[0]&7);
                                iArray[3]=(b & 0x1F)<<3;
                                try {
                                    raster.setPixel(x +dx, y +dy, iArray);
                                }catch (Exception e) {

                                }finally{
                                    x++;
                                }
                            } else if (b != 0) {// ???
                                count = b & 0x1F;// count
                                b = in.read();// alpha
                                index = in.read();
                                c = palette[index];
                                iArray[0]=((c >>> 11) & 0x1F);
                                iArray[1]=((c >>> 5 ) & 0x3f);
                                iArray[2]=( c & 0x1F);
                                iArray[0]=(iArray[0]<<3)|(iArray[0]&7);
                                iArray[1]=(iArray[1]<<2)|(iArray[0]&3);
                                iArray[2]=(iArray[2]<<3)|(iArray[0]&7);
                                iArray[3]=(b & 0x1F)<<3;
                                for (int i = 0; i < count; i++) {
                                    try {
                                        raster.setPixel(x +dx, y +dy, iArray);
                                    }catch (Exception e) {

                                    }finally{
                                        x++;
                                    }
                                }
                            } else {// block end
                                if (x==0 &&y > 0) {//x还是0的时候 复制上一行的数据
                                    int yTwo = y - 1;
                                    for (int i = x; i < frameWidth; i++) {
                                        raster.setPixel(i, y, raster.getPixel(i, yTwo, iArray));
                                    }
                                }
                                break ss;
                            }
                            break;
                        case TYPE_PIXELS:
                            count = b & 0x3F;
                            for (int i = 0; i < count; i++) {
                                index = in.read();
                                iArray[0]=((palette[index] >>> 11) & 0x1F);
                                iArray[1]=((palette[index] >>> 5 ) & 0x3f);
                                iArray[2]=( palette[index] & 0x1F);
                                iArray[0]=(iArray[0]<<3)|(iArray[0]&7);
                                iArray[1]=(iArray[1]<<2)|(iArray[0]&3);
                                iArray[2]=(iArray[2]<<3)|(iArray[0]&7);
                                iArray[3]=0x1F<<3;
                                try {
                                    raster.setPixel(x +dx, y +dy, iArray);
                                }catch (Exception e) {

                                }finally{
                                    x++;
                                }
                            }
                            break;
                        case TYPE_REPEAT:
                            count = b & 0x3F;
                            index = in.read();
                            c = palette[index];
                            iArray[0]=((c >>> 11) & 0x1F);
                            iArray[1]=((c >>> 5 ) & 0x3f);
                            iArray[2]=( c & 0x1F);
                            iArray[0]=(iArray[0]<<3)|(iArray[0]&7);
                            iArray[1]=(iArray[1]<<2)|(iArray[0]&3);
                            iArray[2]=(iArray[2]<<3)|(iArray[0]&7);
                            iArray[3]= 0x1F<<3;
                            for (int i = 0; i < count; i++) {
                                try {
                                    raster.setPixel(x +dx, y +dy, iArray);
                                }catch (Exception e) {

                                }finally{
                                    x++;
                                }
                            }
                            break;
                        case TYPE_SKIP:
                            count = b & 0x3F;
                            x += count;
                            break;
                        default:
                            break ss;
                    }
                }
                if (x > frameWidth) {
                    System.err.println("block end error: [" + y + "][" + x + "/" + frameWidth + "]");
                }
            }
            return image;
        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
        }
        return image;
    }
    /**是否要偷工减料*/
    public static boolean isV(String filename) {
        s:for (int i = 0; i < 11; i++) {
            if (filename.endsWith(vvv[i])) {
                for (int j = 11; j < vvv.length; j++) {
                    if (filename.indexOf(vvv[j])!=-1) {break s;}
                }
                return true;
            }
        }
        return false;
    }
    /**路径判断动作类型*/
    public static int getAct(String filename) {
        if (filename.length()<=4) { return -1; }
        filename=filename.substring(0, filename.length()-4);
        for (int i = 0; i < ActionType.length; i++) {
            if (filename.endsWith(ActionType[i])) {
                return i;
            }
        }
        return -1;
    }
    /**方向调整*/
    public static int changdir(int dir, int size) {
        if (size == 2) {
            return dir==3?0:1;
        }else {
            switch (dir) {
                case 0:dir = 6;break;
                case 1:dir = 3;break;
                case 2:dir = 7;break;
                case 3:dir = 0;break;
                case 4:dir = 4;break;
                case 5:dir = 1;break;
                case 6:dir = 5;break;
                case 7:dir = 2;break;
                default:break;
            }
        }
        return dir;
    }

    /**获取动作*/
    public static String getActionType(int type) { return ActionType[type]; }
    public static HHOne[] getHHOne(long skin){
        HHOne[] ones=indexMap.get(skin);
        if (ones==null&&skin>0x7FFFFFFF&&(skin>>32)>18) {
            ones=indexMap.get((((skin>>32)-18)<<32|(int)skin));
        }
        return ones;
    }

//TODO 玩家主模型替换（原本缺少影子）
    /**创建NewPart对象*/
    public static NewPart createPart(String skin, int act, int lvl,String color){
        //system.out.println(skin);
        if (skin==null){
            skin="大话精灵";
        }
        // 快速修复：处理玄天姬双环武器问题
        if ("22008".equals(skin)) {
            // 使用玄天姬双环武器皮肤ID
            skin = "47244662264";
        }
        ConfigureBean allConfigure = UserMessUntil.getConfigureBean();
        Map<BigDecimal, Configure> item = allConfigure.getAllConfigure();
        Configure configure = item.get(new BigDecimal(1));
        String nao = "新";
        if(configure.getNeworold()!=null) {
            nao = configure.getNeworold();
        }
        if (color!=null&&color.equals("null")){
            nao="旧";
            color=null;
        }
        if("新".equals(nao)) {
            if("6936372203050".equals(skin)) {
                skin = "81604398634";
            }
            if("26225070329377".equals(skin)) {
                skin = "85899365921";
            }
            if("26276609938932".equals(skin)) {
                skin = "120259106292";
            }//
            if("26216480395791".equals(skin)) {
                skin = "128849039887";
            }//
            if("26276609937936".equals(skin)) {
                skin = "120259105296";
            }//
            if("26276609937937".equals(skin)) {
                skin = "120259105297";
            }//
            if("26199300526605".equals(skin)) {
                skin = "81604399629";
            }//
            if("26199300527609".equals(skin)) {
                skin = "81604400633";
            }//
            if("26225070329385".equals(skin)) {
                skin = "85899365929";
            }//
            if("26199300528601".equals(skin)) {
                skin = "81604401625";
            }//
            if("26289494841821".equals(skin)) {
                skin = "150323878365";
            }//
            if("26199300529601".equals(skin)) {
                skin = "81604402625";
            }//
            if("26216480398789".equals(skin)) {
                skin = "128849042885";
            }//
            if(skin.equals("20007")) {
                skin = "81604398631";
            }//飞剑侠剑皮肤
            if(skin.equals("24001")) {
                skin = "81604402625";
            }//沧浪君光武剑皮肤
            if(skin.equals("22002")) {
                skin = "81604400626";
            }//老头仙剑皮肤
            if(skin.equals("20001")) {
                skin = "85899365921";
            }//逍遥生扇子皮肤
            if(skin.equals("20002")) {
                skin = "90194333218";
            }//剑侠客锤子皮肤
            if(skin.equals("20003")) {
                skin = "94489300515";
            }//丑男人斧子皮肤
            if(skin.equals("20009")) {
                skin = "85899365929";
            }//纯阳子 扇子皮肤
            if(skin.equals("21001")) {
                skin = "107374203401";
            }//
            if(skin.equals("20004")) {
                skin = "111669169700";
            }//
            if(skin.equals("20005")) {
                skin = "120259104293";
            }//
            if(skin.equals("20006")) {
                skin = "128849038886";
            }//
            if(skin.equals("20008")) {
                skin = "81604398632";
            }//
            if(skin.equals("20010")) {
                skin = "81604398634";
            }//
            if(skin.equals("21002")) {
                skin = "133144007178";
            }//
            if(skin.equals("21003")) {
                skin = "120259105291";
            }//
            if(skin.equals("21007")) {
                skin = "128849039887";
            }//
            if(skin.equals("21009")) {
                skin = "120259105297";
            }
            if(skin.equals("21004")) {
                skin = "120259105292";
            }
            if(skin.equals("21005")) {
                skin = "81604399629";
            }
            if(skin.equals("21006")) {
                skin = "111669170702";
            }
            if(skin.equals("21008")) {
                skin = "120259105296";
            }
            if(skin.equals("21010")) {
                skin = "115964138002";
            }
            if(skin.equals("22001")) {
                skin = "128849040881";
            }
            if(skin.equals("22003")) {
                skin = "107374204403";
            }
            if(skin.equals("22007")) {
                skin = "128849040887";
            }
            if(skin.equals("22009")) {
                skin = "81604400633";
            }
            if(skin.equals("22004")) {
                skin = "120259106292";
            }
            if(skin.equals("22005")) {
                skin = "146028910069";
            }
            if(skin.equals("22006")) {
                skin = "81604400630";
            }
            if(skin.equals("22008")) {
                skin = "146028910072";
            }
            if(skin.equals("22010")) {
                skin = "146028910074";
            }
            if(skin.equals("23001")) {
                skin = "81604401625";
            }
            if(skin.equals("23002")) {
                skin = "128849041882";
            }
            if(skin.equals("23003")) {
                skin = "103079238107";
            }
            if(skin.equals("23004")) {
                skin = "111669172700";
            }
            if(skin.equals("23005")) {
                skin = "150323878365";
            }
            if(skin.equals("23006")) {
                skin = "146028911070";
            }
            if(skin.equals("24002")) {
                skin = "128849042882";
            }
            if(skin.equals("24003")) {
                skin = "154618846659";
            }
            if(skin.equals("24004")) {
                skin = "90194337220";
            }
            if(skin.equals("24006")) {
                skin = "81604402630";
            }
            if(skin.equals("24005")) {
                skin = "128849042885";
            }
            if(skin.equals("120259105299")) {
                skin = "42949693971";
            }
            if(skin.equals("128849039891")) {
                skin = "51539628563";
            }
            if(skin.equals("120259105300")) {
                skin = "42949693972";
            }
            if(skin.equals("115964138004")) {
                skin = "38654726676";
            }
            if(skin.equals("107374202411")) {
                skin = "30064791083";
            }
            if(skin.equals("81604398635")) {
                skin = "4294987307";
            }
            if(skin.equals("120259104300")) {
                skin = "42949692972";
            }
            if(skin.equals("111669169708")) {
                skin = "34359758380";
            }
            if(skin.equals("128849040891")) {
                skin = "51539629563";
            }
            if(skin.equals("107374204411")) {
                skin = "30064793083";
            }
            if(skin.equals("146028910076")) {
                skin = "68719498748";
            }
            if(skin.equals("124554073596")) {
                skin = "47244662268";
            }
            if(skin.equals("81604401631")) {
                skin = "4294990303";
            }
            if(skin.equals("120259107295")) {
                skin = "42949695967";
            }
            if(skin.equals("120259108295")) {
                skin = "42949696967";
            }
            if(skin.equals("81604402631")) {
                skin = "4294991303";
            }
            if(skin.equals("146028912072")) {
                skin = "68719500744";
            }
            if(skin.equals("150323879368")) {
                skin = "73014468040";
            }

        }
        if (color!=null) { color=TCPLoadThread.addMap(color); }
        NewPart part=null;

        // 只使用MODEL映射(skin文件)，移除HH文件相关逻辑
        if (Xy2Util.MODEL.containsKey(skin)) {
            // 使用MODEL映射中的skin文件
            part=new PartOne(Xy2Util.MODEL.get(skin), act, lvl, color);
        } else {
            // 如果没有MODEL映射，使用默认PartOne
            part=new PartOne(skin, act, lvl, color);
        }

        return part;
    }

    //TODO 玩家坐骑主模型替换（原本缺少影子）
    public static NewPart createPart(long skin, int act, int lvl,String color){
        if (color!=null) { color=TCPLoadThread.addMap(color); }
        NewPart part=null;
        // 获取最新的配置而不是使用静态变量
        ConfigureBean allConfigure = UserMessUntil.getConfigureBean();
        Map<BigDecimal, Configure> item = allConfigure.getAllConfigure();
        Configure configure = item.get(new BigDecimal(1));
        String nao = "新";
        if(configure.getNeworold()!=null) {
            nao = configure.getNeworold();
        }

        // 检查是否为第八个坐骑皮肤 (ID范围检查)
        boolean isEighthMount = (skin >= 8796093053409L && skin <= 8796093057416L);

        // 检查是否为其他支持的坐骑皮肤
        boolean isSupportedMount = (skin==1099511647787L||skin==2199023275563L||skin==3298534903339L||skin==4398046531115L||skin==5497558158891L||skin==6597069786667L||skin==7696581414443L
                ||skin==7696581414444L||skin==6597069786668L||skin==5497558158892L||skin==4398046531116L||skin==3298534903340L||skin==2199023275564L||skin==1099511647788L
                ||skin==7696581415443L||skin==6597069787667L||skin==5497558159891L||skin==4398046532115L||skin==3298534904339L||skin==2199023276563L||skin==1099511648787L
                ||skin==7696581415444L||skin==6597069787668L||skin==5497558159892L||skin==4398046532116L||skin==3298534904340L||skin==2199023276564L||skin==1099511648788L
                ||skin==7696581416443L||skin==6597069788667L||skin==5497558160891L||skin==4398046533115L||skin==3298534905339L||skin==1099511649787L||skin==2199023277563L
                ||skin==7696581416444L||skin==6597069788668L||skin==5497558160892L||skin==4398046533116L||skin==3298534905340L||skin==2199023277564L||skin==1099511649788L
                ||skin==1099511650783L||skin==2199023278559L||skin==3298534906335L||skin==4398046534111L||skin==5497558161887L||skin==6597069789663L||skin==7696581417439L
                ||skin==1099511650784L||skin==2199023278560L||skin==3298534906336L||skin==4398046534112L||skin==5497558161888L||skin==6597069789664L||skin==7696581417440L
                ||skin==1099511651783L||skin==2199023279559L||skin==3298534907335L||skin==4398046535111L||skin==5497558162887L||skin==6597069790663L||skin==7696581418439L
                ||skin==1099511651784L||skin==2199023279560L||skin==3298534907336L||skin==4398046535112L||skin==5497558162888L||skin==6597069790664L||skin==7696581418440L)
                || isEighthMount; // 添加第八个坐骑皮肤支持

        // 只使用MODEL映射(skin文件)，移除HH文件相关逻辑
        // 特殊处理第八个坐骑皮肤
        if (isEighthMount) {
            // 对于第八个坐骑皮肤，优先使用MODEL映射
            if (Xy2Util.MODEL.containsKey(skin+"")) {
                part=new PartOne(Xy2Util.MODEL.get(skin+""), act, lvl, color);
            } else {
                // 如果MODEL中没有映射，则使用默认处理
                part=new PartOne(skin+"", act, lvl, color);
            }
        } else if (Xy2Util.MODEL.containsKey(skin+"")) {
            // 优先使用MODEL映射中的skin文件
            part=new PartOne(Xy2Util.MODEL.get(skin+""), act, lvl, color);
        } else if (isSupportedMount) {
            // 对于支持的坐骑皮肤，直接使用PartOne处理
            part=new PartOne(skin+"", act, lvl, color);
        } else {
            // 如果没有MODEL映射，使用默认PartOne
            part=new PartOne(skin+"", act, lvl, color);
        }

        return part;
    }

    public static NewPart setPart(NewPart newPart,int lvl,String skin){
//  //system.out.println(skin);
        try {
            ConfigureBean allConfigure = UserMessUntil.getConfigureBean();
            Map<BigDecimal, Configure> item = allConfigure.getAllConfigure();
            Configure configure = item.get(new BigDecimal(1));
            String nao = "新";
            if(configure.getNeworold()!=null) {
                nao = configure.getNeworold();
            }

            // 修改资源加载优先级：只使用MODEL映射(skin文件)
            if(Long.parseLong(skin)>=20001 && Long.parseLong(skin)<=22010) {
                newPart.setAct(2);
            }else if(Long.parseLong(skin)>=23001 && Long.parseLong(skin)<=23006) {
                newPart.setAct(2);
            }else if(Long.parseLong(skin)>=24001 && Long.parseLong(skin)<=24006) {
                newPart.setAct(2);
            }else{
                newPart.setAct(7);
            }

            // 只检查MODEL映射
            if (Xy2Util.MODEL.containsKey(skin+"")) {
                return newPart.setPart(lvl,Xy2Util.MODEL.get(skin+""));
            }
        } catch (Exception e) {
            // TODO: handle exception
        }
        return newPart.setPart(lvl, skin);
    }

    /**
     * 关闭TCP加载线程的方法
     * 用于在程序退出时正确关闭线程，释放资源
     */
    public static void shutdownTcpLoadThread() {
        if (thread != null && thread.isAlive()) {
            thread.interrupt();
            try {
                thread.join(1000); // 等待最多1秒
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }
    }
}
